package com.tudouji.project.purchasebill.service.impl;

import com.flow.service.pojo.BasePojo;
import com.flow.service.pojo.ResultParam;
import com.flow.service.pojo.flow.FlowTempNode;
import com.flow.service.pojo.result.FlowResult;
import com.flow.service.process.service.IFlowBaseService;
import com.flow.service.process.service.impl.FlowProcessProxy;
import com.flow.service.process.service.impl.FlowTempNodeServiceImpl;
import com.github.pagehelper.PageHelper;
import com.tudouji.common.exception.CustomException;
import com.tudouji.common.utils.DateUtils;
import com.tudouji.common.utils.IdUtils;
import com.tudouji.common.utils.SecurityUtils;
import com.tudouji.common.utils.sql.SqlUtil;
import com.tudouji.framework.web.domain.AjaxResult;
import com.tudouji.framework.web.page.PageDomain;
import com.tudouji.framework.web.page.TableSupport;
import com.tudouji.project.bill.domain.Whinfo;
import com.tudouji.project.bill.domain.Whinform;
import com.tudouji.project.bill.domain.Whinformitem;
import com.tudouji.project.bill.mapper.WhinformMapper;
import com.tudouji.project.bill.mapper.WhinformitemMapper;
import com.tudouji.project.bill.service.IWhinfoService;
import com.tudouji.project.bill.service.IWhinformService;
import com.tudouji.project.flow.utils.FlowProcessUtil;
import com.tudouji.project.organization.domain.Organization;
import com.tudouji.project.organization.mapper.OrganizationMapper;
import com.tudouji.project.permission.domain.Salespermission;
import com.tudouji.project.permission.service.impl.SalespermissionServiceImpl;
import com.tudouji.project.product.domain.Productinfo;
import com.tudouji.project.product.domain.Salesspecification;
import com.tudouji.project.product.mapper.ProductinfoMapper;
import com.tudouji.project.product.mapper.SalesspecificationMapper;
import com.tudouji.project.purchasebill.domain.Purchasebill;
import com.tudouji.project.purchasebill.domain.Purchasebillitem;
import com.tudouji.project.purchasebill.mapper.PurchasebillMapper;
import com.tudouji.project.purchasebill.mapper.PurchasebillitemMapper;
import com.tudouji.project.purchasebill.service.IPurchasebillService;
import com.tudouji.project.store.domain.Stockunit;
import com.tudouji.project.store.domain.Storehouseroom;
import com.tudouji.project.store.domain.Storeroom;
import com.tudouji.project.store.mapper.StockunitMapper;
import com.tudouji.project.store.mapper.StorehouseroomMapper;
import com.tudouji.project.store.mapper.StoreroomMapper;
import com.tudouji.project.system.domain.SysDept;
import com.tudouji.project.system.domain.SysUser;
import com.tudouji.project.system.mapper.SysDeptMapper;
import com.tudouji.project.system.service.impl.BusinesscodeServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 采购单Service业务层处理
 *
 * @author tudouji
 * @date 2022-04-11
 */
@Slf4j
@Service
public class PurchasebillServiceImpl implements IPurchasebillService, IFlowBaseService {
    @Autowired
    private PurchasebillMapper purchasebillMapper;
    @Autowired
    private BusinesscodeServiceImpl businesscodeService;
    @Autowired
    private FlowTempNodeServiceImpl nodeService;
    @Autowired
    private FlowProcessUtil processUtils;
    @Autowired
    private FlowProcessProxy flowProcessProxy;
    @Autowired
    private PurchasebillitemMapper purchasebillitemMapper;
    @Autowired
    private SalespermissionServiceImpl permissionService;
    @Autowired
    private StorehouseroomMapper storehouseroomMapper;
    @Autowired
    private StoreroomMapper storeroomMapper;
    @Autowired
    private OrganizationMapper organizationMapper;
    @Autowired
    private SalesspecificationMapper salesspecificationMapper;
    @Autowired
    private StockunitMapper stockunitMapper;
    @Autowired
    private WhinformMapper whinformMapper;
    @Autowired
    private IWhinformService whinformService;
    @Autowired
    private WhinformitemMapper whinformitemMapper;
    @Autowired
    private IWhinfoService whinfoService;
    @Autowired
    private ProductinfoMapper productinfoMapper;
    @Autowired
    private SysDeptMapper deptMapper;

    /**
     * 查询采购单
     *
     * @param guid 采购单ID
     * @return 采购单
     */
    @Override
    public Purchasebill selectPurchasebillById(Long guid) {
        return purchasebillMapper.selectPurchasebillById(guid);
    }

    /**
     * 查询采购单
     *
     * @param code 采购单code
     * @return 采购单
     */
    @Override
    public Purchasebill selectPurchasebillByCode(String code) {
        return purchasebillMapper.selectPurchasebillByCode(code);
    }

    /**
     * 采购查询是否有入库单，如果没有可以删除；
     */
    @Override
    public AjaxResult del(Long id) {
        Purchasebill pl = purchasebillMapper.selectPurchasebillById(id);
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        Whinform whinform = new Whinform();
        whinform.setFoguid(pl.getGuid());
        List<Whinform> whinforms = whinformMapper.selectWhinformList(whinform);
        if (whinforms.size() == 0) {
            Purchasebill purchasebill = new Purchasebill();
            purchasebill.setId(id);
            purchasebill.setStatus(0);
            purchasebillMapper.updatePurchasebill(purchasebill);
            //更新待处理任务
            processUtils.updateTaskByOrderId(id, sysUser, Long.valueOf(pl.getFlowtempguid()));
            return AjaxResult.success();
        } else {
            return AjaxResult.error("已入库不能删除！");
        }
    }

    /**
     *
     */
    @Override
    public AjaxResult delPc(Long id) {
        Purchasebill pl = purchasebillMapper.selectPurchasebillById(id);
        if (1 == pl.getStatus()) {
            Purchasebillitem Purchasebillitem = new Purchasebillitem();
            Purchasebillitem.setPurchaseguid(pl.getGuid());
            List<Purchasebillitem> items = purchasebillitemMapper.selectPurchasebillitemList(Purchasebillitem);
            for (int i = 0; i < items.size(); i++) {
                purchasebillitemMapper.deletePurchasebillitemById(items.get(i).getGuid());
            }
            purchasebillMapper.deletePurchasebillById(id);
            return AjaxResult.success();
        } else {
            return AjaxResult.error("非草稿状态，不能删除！");
        }
    }

    /**
     * 设置请求分页数据
     */
    protected void startPage() {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (com.tudouji.common.utils.StringUtils.isNotNull(pageNum) && com.tudouji.common.utils.StringUtils.isNotNull(pageSize)) {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

    /**
     * 查询采购单列表
     *
     * @param purchasebill 采购单
     * @param status
     * @param functionType
     * @return 采购单
     */
    @Override
    public List<Purchasebill> selectPurchasebillList(Purchasebill purchasebill, String status, String functionType) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (purchasebill == null) {
            purchasebill = new Purchasebill();
        }

        if (org.apache.commons.lang.StringUtils.isNotBlank(status)) {
            if (status.equals("00")) {// 待处理
                purchasebill.setCreateBy(sysUser.getUserId());
                startPage();
                return purchasebillMapper.selectPurchasebillPendingList(purchasebill);
            } else {
                String[] sts = status.split(",");
                Integer[] stss = (Integer[]) ConvertUtils.convert(sts, Integer.class);
                purchasebill.setStats(stss);
            }
        }
        //查询是否有全局权限
        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        if (permissions.size() > 0) {
            startPage();
            return purchasebillMapper.selectPurchasebillList(purchasebill);
        } else {
            purchasebill.setCreateBy(sysUser.getUserId());
            // 是否有组织权限
            List<Salespermission> permissionsOrg = permissionService
                    .getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "7");
            //是否有部门权限
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "2");

            startPage();
            if (permissions.size() > 0 || permissionsOrg.size() > 0) {
                String[] deptids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    deptids[i] = permissions.get(i).getDepartid();
                }
                String[] roomids = new String[permissionsOrg.size()];
                for (int i = 0; i < permissionsOrg.size(); i++) {
                    roomids[i] = permissionsOrg.get(i).getSrguid();
                }
                purchasebill.setRoomids(roomids);
                purchasebill.setDepids(deptids);
                return purchasebillMapper.selectPurchasebillsByDep(purchasebill);
            } else {
                //查询个人的
                return purchasebillMapper.selectPurchasebillsByUser(purchasebill);
            }
        }
    }

    /**
     * 查询采购单列表
     *
     * @param purchasebill 采购单
     * @param status
     * @param functionType
     * @return 采购单
     */
    @Override
    public List<Purchasebill> listPC(Purchasebill purchasebill, String status, String functionType) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (purchasebill == null) {
            purchasebill = new Purchasebill();
        }

        if (org.apache.commons.lang.StringUtils.isNotBlank(status)) {
            String[] sts = status.split(",");
            Integer[] stss = (Integer[]) ConvertUtils.convert(sts, Integer.class);
            purchasebill.setStats(stss);
        }
        //查询是否有全局权限
        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        if (permissions.size() > 0) {
            startPage();
            return purchasebillMapper.selectPurchasebillListPc(purchasebill);
        } else {
            purchasebill.setCreateBy(sysUser.getUserId());
            // 是否有组织权限
            List<Salespermission> permissionsOrg = permissionService
                    .getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "7");
            //是否有部门权限
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "2");

            startPage();
            if (permissions.size() > 0 || permissionsOrg.size() > 0) {
                String[] deptids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    deptids[i] = permissions.get(i).getDepartid();
                }
                String[] roomids = new String[permissionsOrg.size()];
                for (int i = 0; i < permissionsOrg.size(); i++) {
                    roomids[i] = permissionsOrg.get(i).getSrguid();
                }
                purchasebill.setRoomids(roomids);
                purchasebill.setDepids(deptids);
                return purchasebillMapper.selectPurchasebillsByDepPc(purchasebill);
            } else {
                //查询个人的
                return purchasebillMapper.selectPurchasebillsByUserPc(purchasebill);
            }
        }
    }

    /**
     * 新增采购单
     *
     * @param purchasebill 采购单
     * @return 结果
     */
    @Override
    public int insertPurchasebill(Purchasebill purchasebill) {
        return purchasebillMapper.insertPurchasebill(purchasebill);
    }

    /**
     * 修改采购单
     *
     * @param purchasebill 采购单
     * @return 结果
     */
    @Override
    public int updatePurchasebill(Purchasebill purchasebill) {
        return purchasebillMapper.updatePurchasebill(purchasebill);
    }

    /**
     * 批量删除采购单
     *
     * @param guids 需要删除的采购单ID
     * @return 结果
     */
    @Override
    public int deletePurchasebillByIds(String[] guids) {
        return purchasebillMapper.deletePurchasebillByIds(guids);
    }

    /**
     * 删除采购单信息
     *
     * @param guid 采购单ID
     * @return 结果
     */
    @Override
    public int deletePurchasebillById(Long guid) {
        return purchasebillMapper.deletePurchasebillById(guid);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult save(Purchasebill entity, String fileIds) {

        Organization organization = organizationMapper.selectOrganizationById(entity.getOrgid());
        Storeroom storeroom = storeroomMapper.selectStoreroomById(Long.valueOf(entity.getSrguid()));

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        String code = businesscodeService.getCode("30");
        entity.setSrguid(storeroom.getGuid());

        entity.setGuid(IdUtils.fastSimpleUUID());
        entity.setCode(code);
        entity.setFlowtempguid("26");
        entity.setOperatorid(sysUser.getGuid());
        entity.setOperator(sysUser.getNickName());
        entity.setCreatetime(new Date());
        BigDecimal totalNum = BigDecimal.ZERO;
        BigDecimal totalAmount = BigDecimal.ZERO;
        if (entity.getItems().size() == 0) {
            return AjaxResult.error("明细不能为空！");
        }
        for (Purchasebillitem item : entity.getItems()) {
            item.setOrgguid(entity.getOrgid());
            item.setOrgname(entity.getOrgname());
            item.setCurrency(entity.getCurrency());
            item.setSrguid(entity.getSrguid());
            totalNum = totalNum.add(item.getCount());
//            item.setAmount(item.getPrice().multiply(item.getCount()));
            totalAmount = totalAmount.add(item.getPrice().multiply(item.getCount()));
        }
        entity.setTotalnum(totalNum);
        entity.setTotalamount(totalAmount);
        entity.setCreateBy(sysUser.getUserId());
        SysDept dept = deptMapper.selectDeptById(entity.getDeptId());
        entity.setDepartid(dept.getGuid());
        entity.setOrgId(organization.getId());
        entity.setStrmId(storeroom.getId());
        this.insertPurchasebill(entity);
        System.out.println("采购明细：" + entity.getItems().size());
        for (Purchasebillitem item : entity.getItems()) {
            item.setGuid(IdUtils.fastSimpleUUID());
            item.setPurchaseguid(entity.getGuid());
            purchasebillitemMapper.insertPurchasebillitem(item);

        }
        // 获取起始节点
        FlowTempNode node = new FlowTempNode();
        node.setNodeType(1);
        node.setFlowtempId(Long.valueOf(entity.getFlowtempguid()));
        node = nodeService.selectFlowTempNodeList(node).get(0);

        entity.setPlatformId(Long.valueOf(storeroom.getId()));
        entity.setSrguid(storeroom.getId() + "");

        FlowResult result = flowProcessProxy.start(node.getId(), entity, fileIds, sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Purchasebill pb = new Purchasebill();
            pb.setId(entity.getId());
            pb.setStatus(result.getNextStat());
            this.updatePurchasebill(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult savePc(Purchasebill entity) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        Organization organization = organizationMapper.selectOrganizationById(entity.getOrgid());
        entity.setOrgname(organization.getName());
        entity.setOrgId(organization.getId());
        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(entity.getSrguid());
        entity.setStrmId(storeroom.getId());
        entity.setSrname(storeroom.getName());
        SysDept dept = deptMapper.selectDeptById(entity.getDeptId());
        entity.setDepartid(dept.getGuid());
        entity.setDepartment(dept.getDeptName());

        BigDecimal totalNum = BigDecimal.ZERO;
        BigDecimal totalAmount = BigDecimal.ZERO;
        if (entity.getItems() != null && entity.getItems().size() != 0) {
            for (Purchasebillitem item : entity.getItems()) {
                item.setOrgguid(entity.getOrgid());
                item.setOrgname(entity.getOrgname());
                item.setCurrency(entity.getCurrency());
                item.setSrguid(entity.getSrguid());
                totalNum = totalNum.add(item.getCount());
//                item.setAmount(item.getPrice().multiply(item.getCount()));
                totalAmount = totalAmount.add(item.getPrice().multiply(item.getCount()));
            }
        }
        entity.setTotalnum(totalNum);
        entity.setTotalamount(totalAmount);

        if (null == entity.getId()){

            String code = businesscodeService.getCode("30");
            entity.setGuid(IdUtils.fastSimpleUUID());
            entity.setCode(code);
            entity.setFlowtempguid("26");
            entity.setOperatorid(sysUser.getGuid());
            entity.setOperator(sysUser.getNickName());
            entity.setCreatetime(DateUtils.getNowDate());
            entity.setStatus(1);
            entity.setCreateBy(sysUser.getUserId());
            this.insertPurchasebill(entity);
        }else{
            this.updatePurchasebill(entity);
        }
        Purchasebill purchasebill = this.selectPurchasebillById(entity.getId());
        if (entity.getItems() != null && entity.getItems().size() != 0) {
            System.out.println("采购明细：" + entity.getItems().size());
            for (Purchasebillitem item : entity.getItems()) {
                if (StringUtils.isBlank(item.getGuid())){
                    item.setGuid(IdUtils.fastSimpleUUID());
                    item.setPurchaseguid(purchasebill.getGuid());
                    purchasebillitemMapper.insertPurchasebillitem(item);
                }else{
                    purchasebillitemMapper.updatePurchasebillitem(item);
                }

            }
        }
        return AjaxResult.success(this.selectPurchasebillById(entity.getId()));
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult startPc(Long id, String imgids) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Purchasebill purchasebill = purchasebillMapper.selectPurchasebillById(id);
        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(purchasebill.getSrguid());
        // 获取起始节点
        FlowTempNode node = new FlowTempNode();
        node.setNodeType(1);
        node.setFlowtempId(Long.valueOf(purchasebill.getFlowtempguid()));
        node = nodeService.selectFlowTempNodeList(node).get(0);

        purchasebill.setPlatformId(Long.valueOf(storeroom.getId()));
        purchasebill.setSrguid(storeroom.getId() + "");

        FlowResult result = flowProcessProxy.start(node.getId(), purchasebill, imgids, sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Purchasebill pb = new Purchasebill();
            pb.setStatus(result.getNextStat());
            pb.setId(id);
            this.updatePurchasebill(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult approval(Long id, String imgids, String opinion, Long taskid) {

        Purchasebill purchasebill = purchasebillMapper.selectPurchasebillById(id);
        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(purchasebill.getSrguid());
        purchasebill.setPlatformId(Long.valueOf(storeroom.getId()));

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        FlowResult result = flowProcessProxy.approval(taskid, imgids, opinion, purchasebill
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Purchasebill pb = new Purchasebill();
            pb.setStatus(result.getNextStat());
            pb.setId(id);
            this.updatePurchasebill(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult refuse(Long id, String fileIds, String opinion, Long taskid, Long refuseNodeid
            , Long backUserid) {
        Purchasebill purchasebill = purchasebillMapper.selectPurchasebillById(id);
        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(purchasebill.getSrguid());
        purchasebill.setPlatformId(Long.valueOf(storeroom.getId()));

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        FlowResult result = flowProcessProxy.refuse(taskid, fileIds, opinion, purchasebill
                , sysUser, refuseNodeid, backUserid);

        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Purchasebill pb = new Purchasebill();
            pb.setStatus(result.getNextStat());
            pb.setId(id);
            this.updatePurchasebill(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult transferIn(Long id, List<Whinformitem> whinitems, String imgids, String opinion, Long taskid, BigDecimal exchangerate) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        BigDecimal totalAmount = BigDecimal.ZERO;

        //2023-06-28多次入库的判断标识更新后调用流程
        if (null != exchangerate){
            Purchasebill purchasebill = new Purchasebill();
            purchasebill.setId(id);
            purchasebill.setExchangerate(exchangerate);
            purchasebillMapper.updatePurchasebill(purchasebill);
        }

        Purchasebill purchasebill = purchasebillMapper.selectPurchasebillById(id);
        if (!(null == whinitems || whinitems.size() == 0)){
            //更新调拨申请单明细入库重量
            for (Whinformitem item : whinitems) {
                Purchasebillitem transferitem = purchasebillitemMapper.selectPurchasebillitemById(item.getApplyitemid());
                BigDecimal loadCount = transferitem.getLoadcount() == null ? item.getWeight() : transferitem.getLoadcount().add(item.getWeight());
                transferitem.setLoadcount(loadCount);
                BigDecimal amount = item.getWeight().multiply(transferitem.getPrice());
                BigDecimal amountItemTotal = transferitem.getAmount() == null ? amount : transferitem.getAmount().add(amount);
                transferitem.setAmount(amountItemTotal);
                totalAmount = totalAmount.add(amountItemTotal);
                purchasebillitemMapper.updatePurchasebillitem(transferitem);
                item.setBusinessUnitId(item.getStockunitid());
                item.setBusinessUnitName(item.getStockunit());
            }
//            Whinform form = setWhinform(sysUser, whinitems, purchasebill);
            //2023-10-25将明细的汇总金额写入到入库单主表中
//            saveWhinfo(whinitems, form);

            //20240123 修改采购入库逻辑
            Whinform form = newSetWhinform(whinitems, purchasebill);
            form.setAmount(totalAmount);
            form.setItems(whinitems);
            whinformService.whin(form, false);
        }

        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(purchasebill.getSrguid());
        purchasebill.setPlatformId(Long.valueOf(storeroom.getId()));

        FlowResult result = flowProcessProxy.approval(taskid, imgids, opinion, purchasebill
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Purchasebill pb = new Purchasebill();
            pb.setStatus(result.getNextStat());
            if (!(null == whinitems || whinitems.size() == 0)) {
                pb.setTotalamount(totalAmount);
            }
            pb.setPaystatus(2);
            pb.setId(id);
            this.updatePurchasebill(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult whinBack(Long id, String imgids, String opinion, Long taskid) {

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Purchasebill bill = purchasebillMapper.selectPurchasebillById(id);
        if (bill.getPaystatus().intValue() > 2) {
            return AjaxResult.error("已发起付款申请，不能退回到发起");
        }
        //反入库
        try {
            whinformService.newWhinBack(sysUser, bill.getGuid());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error();
        }

        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(bill.getSrguid());
        bill.setPlatformId(Long.valueOf(storeroom.getId()));
        FlowResult result = flowProcessProxy.approval(taskid, imgids, opinion, bill, sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Purchasebill pb = new Purchasebill();
            pb.setStatus(result.getNextStat());
            pb.setId(id);
            this.updatePurchasebill(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }


    private Whinform newSetWhinform(List<Whinformitem> items, Purchasebill pb) {
        //组装入库单
        Whinform form = new Whinform();
        form.setDepartmentid(pb.getDepartid());
        form.setStorermguid(pb.getSrguid());
        form.setBusinesscode(pb.getCode());
        form.setFoguid(pb.getGuid());
        form.setOrgguid(pb.getOrgid());
        form.setOrgname(pb.getOrgname());
        form.setWhintype(9);
        form.setSupplierId(Long.valueOf(pb.getSupplierid()));
        form.setSupplierName(pb.getSupplier());
        form.setCurrency(pb.getCurrency());
        form.setSettlOrgId(pb.getOrgid());
        form.setSettlOrgName(pb.getOrgname());

        for (Whinformitem item : items) {
            Purchasebillitem pbitem = purchasebillitemMapper.selectPurchasebillitemById(item.getApplyitemid());
            item.setSpguid(pbitem.getSpguid());
            item.setProductguid(pbitem.getProductguid());
            item.setBweight(item.getWeight());
            item.setBusinessUnitId(pbitem.getStockunitid());
            item.setItemguid(item.getApplyitemid());
            item.setPrice(pbitem.getPrice());
            item.setAmount(pbitem.getAmount());
        }
        return form;
    }

    private Whinform setWhinform(SysUser user, List<Whinformitem> items, Purchasebill pb) {
        //组装入库单
        Whinform form = new Whinform();
        form.setCreatedate(DateUtils.getNowDate());
        form.setGuid(IdUtils.fastSimpleUUID());
        form.setDepartmentid(pb.getDepartid());
        form.setStorermguid(pb.getSrguid());
        form.setBusinesscode(pb.getCode());
        form.setFoguid(pb.getGuid());
        form.setOperatorid(user.getGuid());
        form.setOrgguid(pb.getOrgid());
        form.setOrgname(pb.getOrgname());
        form.setWhintype(9);
        form.setSupplierId(Long.valueOf(pb.getSupplierid()));
        form.setSupplierName(pb.getSupplier());
        form.setCurrency(pb.getCurrency());
        form.setSettlOrgId(pb.getOrgid());
        form.setSettlOrgName(pb.getOrgname());
        form.setFormno(businesscodeService.getCode("4"));
        for (Whinformitem item : items) {
            //获取库间
            Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());

            Purchasebillitem pbitem = purchasebillitemMapper.selectPurchasebillitemById(item.getApplyitemid());

            Salesspecification spe = salesspecificationMapper.selectSalesspecificationById(pbitem.getSpguid());
            item.setGuid(IdUtils.fastSimpleUUID());
            item.setSpguid(pbitem.getSpguid());
            item.setSrguid(form.getStorermguid());
            item.setProductguid(pbitem.getProductguid());
            item.setOrgguid(form.getOrgguid());
            item.setOrgname(form.getOrgname());
            item.setBweight(item.getWeight());
            if (spe.getStockunitid() == pbitem.getStockunitid()) {//判断是否以库存单位下单
                item.setStockunitid(pbitem.getStockunitid());
                item.setStockunit(pbitem.getStockunit());
            } else {
                item.setStockunitid(spe.getStockunitid());
                item.setStockunit(spe.getStockunit());
                BigDecimal newWeight = qtyToWeight(pbitem.getStockunitid(), spe.getStockunitid(), pbitem.getSpguid(), item.getWeight());
                item.setWeight(newWeight);
            }
            BigDecimal priceRecover = item.getBweight().multiply(pbitem.getPrice()).divide(item.getWeight(),6, BigDecimal.ROUND_DOWN);
            item.setPrice(priceRecover);
//            BigDecimal amount = item.getPrice().multiply(item.getWeight());
            item.setAmount(pbitem.getAmount());
        }
        return form;
    }

    /**
     * 数量转重量 （转换为公斤）
     *
     * @param fromUnitid 需要转换的单位
     * @param toUnitid   最终转换成的单位
     * @param speguid    物料id
     * @param count      数量
     * @return
     */
    public BigDecimal qtyToWeight(Long fromUnitid, Long toUnitid, String speguid, BigDecimal count) {
        Stockunit unit = stockunitMapper.selectStockunitById(fromUnitid);

        if (unit.getIsUnit() == 1) {//重量单位 被转的是重量单位 直接返回数量count
            return weightToWeight(fromUnitid, toUnitid, count);
        }
        Salesspecification spe = salesspecificationMapper.selectSalesspecificationById(speguid);

        BigDecimal weight = new BigDecimal(0);
        weight = spe.getNetweight().multiply(count).setScale(6, BigDecimal.ROUND_HALF_UP);
        weight = weightToWeight(3l, toUnitid, weight);
        return weight;
    }

    /**
     * 重量转重量
     *
     * @param fromUnitid 需要转换的单位
     * @param toUnitid   最终转换成的单位
     * @param count      数量
     * @return
     */
    public BigDecimal weightToWeight(Long fromUnitid, Long toUnitid, BigDecimal count) {
        BigDecimal weight = new BigDecimal(0);
        if (fromUnitid == toUnitid) {
            return count;
        }
        Stockunit unit = stockunitMapper.selectStockunitById(fromUnitid);
        if (unit.getIsUnit() == 2) {//数量单位
            return count;
        }
        Stockunit unit2 = stockunitMapper.selectStockunitById(toUnitid);
        if (unit2.getIsUnit() == 2) {//数量单位
            return count;
        }
        //单位转换
        weight = count.multiply(unit.getToT()).divide(unit2.getToT(), 6, BigDecimal.ROUND_HALF_UP);
        return weight;
    }


    /**
     * 生产入库信息保存
     *
     * @param form
     * @throws Exception
     */
    public String saveWhinfo(List<Whinformitem> items, Whinform form) {
        whinformMapper.insertWhinform(form);
        form = whinformMapper.selectWhinformById(form.getAutoid());
        String guid = form.getGuid();
        //完善入库明细
        BigDecimal weight = new BigDecimal(0);
        for (Whinformitem item : items) {
            item.setWhinid(guid);
            item.setSrguid(form.getStorermguid());
            item.setOrgguid(form.getOrgguid());
            item.setOrgname(form.getOrgname());

            if (org.apache.commons.lang.StringUtils.isNotBlank(item.getSpguid())) {
                Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
                if (1 == house.getShrtype()) {
                    //原材料  写入统一规格
                    Salesspecification spe = new Salesspecification();
                    spe.setProductguid(item.getProductguid());
                    spe.setBaseFlag(1);
                    spe = salesspecificationMapper.selectSalesspecificationList(spe).get(0);

                    item.setSpename(spe.getName());
                    item.setSpguid(spe.getGuid());
                }
            }

            item.setItemguid(item.getApplyitemid());
            item.setCreateTime(DateUtils.getNowDate());
            item.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whinformitemMapper.insertWhinformitem(item);

            weight = weight.add(item.getWeight());
            // 更新库存信息
            Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
            Whinfo info;
            if (form.getWhintype() == 8) {
                info = whinfoService.getFarmerWhinfo(item.getProductguid(), item.getSrguid(),
                        item.getShrguid());
            } else {
//            	if(house.getShrtype()!=1){//1-原材料库，2-产成品库 3-废品库（不合格品库） 4-辅料
                if (StringUtils.isNotBlank(item.getSpguid())) {
                    info = whinfoService.getWhinfo(form.getOrgguid(), item.getProductguid(), item.getSrguid(),
                            item.getShrguid(), item.getSpguid());
                } else {
                    //回滚
//                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    return "nospguid";//没有规格id
                    throw new CustomException("明细规格有误！");
                }
//                }else{
//                	info = infoService.getWhinfo(form.getOrgguid(), item.getProductguid(), item.getSrguid(),
//                            item.getShrguid());
//                }
            }

            if (info != null) {
                //采收入库的时候计算加权平均价格
//                if (form.getWhintype() == 1) {
//                    info.setPrice(((info.getStoreqty().multiply(info.getPrice() == null ? BigDecimal.ZERO : info.getPrice()).add(form.getQty().multiply(form.getPrice())))
//                            .divide((info.getStoreqty().add(form.getQty())), 2, BigDecimal.ROUND_DOWN)));
//                }

                if (info.getPrice() == null){
                    info.setPrice(item.getPrice());
                }else{
                    info.setPrice(((info.getStoreqty().multiply(info.getPrice()).add(item.getWeight().multiply(item.getPrice())))
                            .divide((info.getStoreqty().add(item.getWeight())), 6, BigDecimal.ROUND_DOWN)));
                }
                info.setStoreqty(info.getStoreqty().add(item.getWeight()));
                info.setLastupdate(DateUtils.getNowDate());
                whinfoService.updateWhinfo(info);
            } else {
                Whinfo whinfo = new Whinfo();
                whinfo.setGuid(IdUtils.fastSimpleUUID());
                whinfo.setStorermguid(item.getSrguid());
                whinfo.setStorehguid(item.getShrguid());
                whinfo.setProductid(item.getProductguid());
                whinfo.setSpguid(item.getSpguid());
                whinfo.setStoreqty(item.getWeight());
                whinfo.setCreatedate(new Date());
                whinfo.setOperatorid(form.getOperatorid());
                whinfo.setOrgguid(form.getOrgguid());
                whinfo.setStockunit(item.getStockunit());
                whinfo.setStockunitid(item.getStockunitid());
                whinfo.setPrice(item.getPrice());
                //获取产品名称
                Productinfo product = productinfoMapper.selectProductinfoById(item.getProductguid());
                whinfo.setProductname(product.getProductname());
                whinfoService.insertWhinfo(whinfo);
            }
        }
        //更新入库单 重量
        Whinform wf = new Whinform();
        if (form.getWhintype() == 8) {
            wf.setWhintype(7);
        }
        wf.setAutoid(form.getAutoid());
        wf.setQty(weight);
        whinformMapper.updateWhinform(wf);
        return guid;
    }

    @Override
    public BasePojo getBaseById(Long id) {
        return selectPurchasebillById(id);
    }

    @Override
    public BasePojo getBaseByCode(String code) {
        return selectPurchasebillByCode(code);
    }
}
